/*
 * Copyright 2009 Max Kugland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.splink.deepsplink.deeplink {
	import org.splink.library.IFinalizable;
	import org.splink.deepsplink.interceptor.IInterceptor;
	import org.splink.deepsplink.navigation.INavigation;
	import org.splink.deepsplink.processor.IProcessor;

	/**
	 * An <code>IDeeplinkController</code> implementation processes page change requests
	 * which originate from within the flash application or in the browser url. These requests
	 * are equally managed regardless of the request source. The request management includes the
	 * application of previously added <code>IInterceptor</code> implementations, of previously
	 * added <code>INavigation</code> implementations and of previously added <code>IProcessor</code>
	 * implementations.
	 * 
	 * @see org.splink.deepsplink.deeplink.DeeplinkController
	 * 
	 * @author Max Kugland
	 */
	public interface IDeeplinkController extends IFinalizable {
		
		/**
		 * Starts loading the first page. If <code>gotoPage</code> has been invoked before 
		 * <code>start</code>, the page which corresponds to the id with which <code>gotoPage</code> 
		 * has been invoked is loaded. If no <code>gotoPage</code> request has been made before
		 * <code>start</code> is executed then the <code>IDeeplinkStrategy</code> identifies
		 * the first page to load.
		 */
		function start() :void;

		/**
		 * Adds an <code>IInterceptor</code> implementation, whose <code>intercept</code> method
		 * is invoked before the actual page change happens. This enables an <code>IInterceptor</code> 
		 * to stop the page changing process and for instance redirect to another page.
		 * It's not possible to add the same interceptor twice
		 * 
		 * @param interceptor the <code>IInterceptor</code> implementation
		 */
		function addInterceptor(interceptor : IInterceptor) : void;

		/**
		 * Removes an <code>IInterceptor</code> implementation.
		 */
		function removeInterceptor(interceptor : IInterceptor) : void;

		/**
		 * Adds an <code>IProcessor</code> implementation. The <code>process</code>
		 * method of the processor is invoked after a <code>gotoPage</code> request
		 * which successfully passed the interceptors.
		 * It's not possible to add the same processor twice
		 * 
		 * @param processor the <code>IProcessor</code> implementation
		 * 
		 * @see org.splink.deepsplink.processor.IProcessor
		 */
		function addProcessor(processor : IProcessor) : void;

		/**
		 * Removes an <code>IProcessor</code> implementation.
		 * 
		 * @param processor the <code>IProcessor</code> implementation to unregister
		 * 
		 * @see org.splink.deepsplink.processor.IProcessor
		 */
		function removeProcessor(processor : IProcessor) : void;

		/**
		 * Registeres an <code>INavigation</code> implementation. The <code>INavigation</code>'s 
		 * <code>select</code> method is invoked before a <code>gotoPage</code> request if this request
		 * doesn't result in a page change because the requested page is already present. In that case
		 * the code>select</code> method's <code>change</code> parameter is set to <code>false</code>
		 * 
		 * If the request is valid and the page has changed, the <code>INavigation</code>'s 
		 * <code>select</code> method is invoked after the successful page change. In that case
		 * the code>select</code> method's <code>change</code> paramteter is set to <code>true</code>
		 * In it's <code>select</code> method an <code>INavigation</code> usually updates it's view. 
 	     *
		 * It's not possible to add the same navigation twice
		 * 
		 * @param navigation the <code>INavigation</code> to add
		 * 
		 * @see org.splink.deepsplink.navigation.INavigation
		 */
		function registerNavigation(navigation : INavigation) : void

		/**
		 * Unregisteres an <code>INavigation</code> implementation.
		 * 
		 * @param navigation the <code>INavigation</code> to register
		 * 
		 * @see org.splink.deepsplink.navigation.INavigation
		 */
		function unregisterNavigation(navigation : INavigation) : void
		
		/**
		 * Instructs to change from the current page to the page the given id referrs to.
		 * If the <code>start</code> method hasn't been executed yet, the <code>gotoPage</code>
		 * invocation has no effect until <code>start</code> is called.
		 * 
		 * @param id the id of the next page to show
		 * @param pageParams the parameters of the page
		 */
		function gotoPage(id : String, pageParams : Array = null) : void;

		/**
		 * <code>onAddressChange</code> is invoked by the <code>IDeeplinkStrategy</code> 
		 * implementation, when the external url changes. 
		 */
		function onAddressChange() : void;
		
		/**
		 * Contains the history of visited pages in an <code>Array</code>. Each element within the
		 * <code>Array</code> is a full page id <code>String</code>.  
		 * 
		 * @return the history <code>Array</code>
		 */
		function get history() : Array;
	}
}
